local game = require "club.threecard.blackjack"
local Time = CS.UnityEngine.Time
local Vector3 = CS.UnityEngine.Vector3
local Color = CS.UnityEngine.Color
local COLOR_ME = Color(0, 0, 0, 1)
local COLOR_OTHER = Color(1, 1, 1, 1)

local seat = game.ui.element()

local log = game.logging.get("seat")

seat.store_watchers = 
{
    ingame =
    {
        ["阶段变更"] = function(self, store, state)
            if state.phase ~= state.PHASE.PLAYER then
                self:on_wait();
            end

            if state.phase == state.PHASE.NULL or state.phase == state.PHASE.IDLE then
                self:clear_bet();
            end
        end,

        ["玩家回合"] = function(self, store, state, args, initialized)
            if initialized then
                return;
            end

            if self.player == nil then
                return;
            end

            if state.current_player == nil then
                return;
            end

            if self.no < state.current_player.seat.no then
                self.poker_container:confirm_amount();
                self.poker_container2:confirm_amount();
            elseif self.no == state.current_player.seat.no then
                if state.current_active_hand_index ~= 0 then
                    self.poker_container:confirm_amount();
                end
            end

            if self.player == state.current_player then
                self:on_turn(state.player_countdown);
            else
                self:on_wait();
            end
        end,
        ["玩家分牌"] = function(self, store, state, args, initialized)
            if initialized then
                return;
            end

            if self.player == nil then
                return;
            end

            local player = args.player;
            if self.player.seat.no ~= player.seat.no then
                return;
            end

            self:on_split();
        end
    },
    room = 
    {
        ["筹码变更"] = function(self, store, state, args, initialized)
            if initialized then
                return;
            end

            local player = args.player;
            if self.no ~= player.seat.no then
                return;
            end

            local old = args.old;
            local current = player.chip;
            self:update_chip(old, current);
        end, 

        ["庄家摸牌"] = function(self, store, state, args, initialized)
            if initialized then
                return;
            end
            
            if self.player == nil then
                return;
            end

            self.poker_container:confirm_amount();
            self.poker_container2:confirm_amount();
        end,

        ["庄家展示底牌"] = function(self, store, state, args, initialized)
            if initialized then
                return;
            end

            if self.player == nil then
                return;
            end

            self.poker_container:confirm_amount();
            self.poker_container2:confirm_amount();
        end
    }
}

function seat:ctor(no)
    self.player = nil;
    self.no = no;
    self.res = "club.threecard.blackjack/ui/ingame.b:seat"

--    local avatar = game.require 'ui.ingame.avatar'
    local AvatarIcon = require "ui.Common.AvatarIcon"
    self.avatar_icon = AvatarIcon.new()
    self.avatar_icon.res = 'club.threecard.blackjack/ui/ingame.b:AvatarIcon'
    local config = game.require "poker_controller.poker_container_config"
    local container = game.require "poker_controller.poker_container"
    self.poker_container = container.new(config, self.no);
    self.poker_container2 = container.new(config, self.no);
end

function seat:load(root)
    self:super("load");
    self.avatar_icon:load();
    self.avatar_icon:set_parent(self.head_root, false);

    if self.should_set_data then
        self:on_set_data();
    end

    self:set_parent(root, false);
    if not root then
        return;
    end

    self.poker_container:set_parent(root:Find("poker_container_root"), false);
    self.poker_container2:set_parent(root:Find("poker_container_root2"), false);
    self.split1_root = root:Find("poker_container_split1_pos");
    self.split2_root = root:Find("poker_container_split2_pos");

    self.bet_split1_root = root:Find("bet_split1_pos");

    --self.poker_container_obj.transform:SetParent(root:Find("poker_container_root"), false);
    --self.poker_container_obj2.transform:SetParent(root:Find("poker_container_root2", false));
    self.bet_root:SetParent(root:Find("bet_root"), false);
    self.bet_root2:SetParent(root:Find("bet_root2"), false);
end

function seat:on_injected(bind)
    self.poker_container:set_gameobject(self.poker_container_obj, true);
    self.poker_container2:set_gameobject(self.poker_container_obj2, true);
end

function seat:set_data(player)
    if not self.loaded then
        self.player = player;
        self.should_set_data = true;
        return;
    end

    self.player = player;
    self:on_set_data();
end

function seat:update_chip(old, current)
    game.utility.digit(self.chip_txt, old, current, game.i18n.styles.chip2);
end

function seat:on_set_data()
    self.should_set_data = false;
    self.poker_container:clear();
    self.poker_container2:clear();

    self.bet_root.gameObject:SetActive(false)
    self.bet_root2.gameObject:SetActive(false)

    if self.player == nil then
        game.audio.post("blackjack:stand_up");
        self.root.gameObject:SetActive(false);
        self.empty_root.gameObject:SetActive(true);
        return;
    end

    self.root.gameObject:SetActive(true);
    self.empty_root.gameObject:SetActive(false);

    local player = self.player;
    self.avatar_icon:set_head(player.head);
    -- self.avatar_icon:set_flag(player.flag);
    self.name_txt.text = player.name;
    self.bet_tip_root.gameObject:SetActive(false);
    self.bet_tip_root2.gameObject:SetActive(false);
    self.time_mask.gameObject:SetActive(false);
    self.countdown_root.gameObject:SetActive(false)
    self:update_chip(0, player.chip);

    if player == game.kbe.player() then
        self.name_txt.color = COLOR_ME
        self.me:SetActive(true);
        self.other:SetActive(false);
        game.gamelib.timer.start(function()
            self.animator:SetTrigger("here");
        end, 0.1);
    else
        self.name_txt.color = COLOR_OTHER
        self.me:SetActive(false);
        self.other:SetActive(true);
    end
end

-- 我的回合
function seat:on_turn(countdown, total)
    if countdown <= 0 then
        return;
    end
    if self.co then
        game.coroutine.stop(self.co);
        self.co = nil;
    end

    if self.player.id == game.kbe.player().id then
        game.audio.post("blackjack:tips_operate");
    end

    self.time_mask.gameObject:SetActive(true);
    self.countdown_root.gameObject:SetActive(true)
    total = total or countdown;
    local warning_point = countdown/2;
    self.co = game.coroutine.ingame_start(function()
        self.time_mask.fillAmount = 1;
        while countdown > 0 do
            countdown = countdown - Time.deltaTime;
            self.time_mask.fillAmount = countdown/total;
            self.countdown_txt.text = math.ceil(countdown)
            if countdown <= warning_point and self.player.id == game.kbe.player().id then
                game.audio.post("blackjack:count_down_three");
                warning_point = -1;
            end
            game.coroutine.step();
        end
    end)
end

function seat:on_split()
    self.poker_container:split_to(self.poker_container2);

    self.poker_container.transform:DOMove(self.split1_root.position, 0.2);
    self.poker_container2.transform:DOMove(self.split2_root.position, 0.2);
end

-- 等待其他玩家
function seat:on_wait()
    if self.co then
        game.coroutine.stop(self.co);
        self.co = nil;
    end

    self.time_mask.gameObject:SetActive(false);
    self.countdown_root.gameObject:SetActive(false)
end

function seat:bet(bet_chip, amount)
    self.bet_root.localPosition = Vector3.zero;
    self.bet_root.gameObject:SetActive(true)
    self.bet_value.text = game.i18n.number(amount, 'chip3')
    do return end

    self.bet_root.localPosition = Vector3.zero;
    local chips = bet_chip:bet(self.bet_root, amount);

    for _, chip in ipairs(chips) do
        chip.transform.position = self.transform.position;
        chip.transform:DOLocalMove(Vector3.zero, 0.5)
        :OnComplete(function()
            self.bet_tip_root.position = chips[#chips].transform.position;
            self.bet_tip_root.gameObject:SetActive(true);
        end)
    end

    self.bet_txt.text = game.i18n.number(amount, "chip3");
end

function seat:bet2(bet_chip, amount)
    self.bet_root2.gameObject:SetActive(true)
    self.bet_value2.text = game.i18n.number(amount, 'chip3')

    self.bet_root:DOMove(self.bet_split1_root.position, 0.3)
    do return end

    local chips = bet_chip:bet(self.bet_root2, amount);

    for _, chip in ipairs(chips) do
        chip.transform.position = self.transform.position;
        chip.transform:DOLocalMove(Vector3.zero, 0.5)
        :OnComplete(function()
            self.bet_tip_root2.position = chips[#chips].transform.position;
            self.bet_tip_root2.gameObject:SetActive(true);
        end)
    end

    self.bet_txt2.text = game.i18n.number(amount, "chip3");

    self.bet_tip_root.gameObject:SetActive(false)
    self.bet_root:DOMove(self.bet_split1_root.position, 0.3)
    :OnComplete(function()
        local chips = bet_chip.parents[self.bet_root];
        if chips and #chips > 0 then
            self.bet_tip_root.position = chips[#chips].transform.position;
            self.bet_tip_root.gameObject:SetActive(true);
        end
    end)
end

function seat:clear_bet()
    self.bet_root.gameObject:SetActive(false)
    self.bet_root2.gameObject:SetActive(false)

    self.bet_tip_root.gameObject:SetActive(false);
    self.bet_tip_root2.gameObject:SetActive(false);
end

function seat:payout(amount)
    self.payout_root_animator:SetTrigger("payout");
    if amount >= 0 then
        self.payout_value.text = string.format("+%s", game.i18n.number(amount, "chip3"));
    else
        self.payout_value.text = game.i18n.number(amount, "chip3");
    end
end

function seat:resume(seats, info, scene)
    local current_no = scene.current_no;
    local total_time = scene.total_time;
    local left_time = scene.left_time;

    self.poker_container:clear();
    self.poker_container:fill(info.hand1_cards);
    self.poker_container:update_poker_amount();
    self.poker_container2:clear();
    self.poker_container2:fill(info.hand2_cards)
    self.poker_container2:update_poker_amount();

    if current_no == self.no then
        local active_hand_index = self.player and self.player.active_hand_index or 0;
        self:on_turn(left_time, total_time, active_hand_index);
    else
        self:on_wait();
    end

    self:bet(seats.bet_chip, info.bet_amount);
    if #info.hand2_cards > 0 then
        self:bet2(seats.bet_chip, info.bet_amount);
        self.poker_container.transform.position = self.split1_root.position;
        self.poker_container2.transform.position = self.split2_root.position;
    end
end

function seat:on_release()
    self:super("on_release")
    if self.co then
        game.coroutine.stop(self.co);
        self.co = nil;
    end

    self.poker_container_obj.transform:SetParent(self.transform, false);
    self.poker_container_obj2.transform:SetParent(self.transform, false)
    self.bet_root:SetParent(self.transform, false);
end

function seat:clear_scene()
    self.poker_container:clear()
    self.poker_container2:clear()
    self:on_wait()
    self:clear_bet()
end

return seat